﻿using Microsoft.Extensions.Logging;
using Sgr.DataCategories.Services;
using System.Diagnostics;

namespace Sgr.DataCategories.BackGroundTasks
{
    public class CategoryCacheRefreshHandle : ICleanupHandle
    {
        private readonly ILogger<CategoryCacheRefreshHandle> _logger;
        private readonly ICategoryItemsManagement _categoryItemsManagement;

        public CategoryCacheRefreshHandle(
            ICategoryItemsManagement categoryItemsManagement,
            ILogger<CategoryCacheRefreshHandle> logger)
        {
            _categoryItemsManagement = categoryItemsManagement ??
                throw new ArgumentNullException(nameof(categoryItemsManagement));
            _logger = logger ??
                throw new ArgumentNullException(nameof(logger));
        }

        public async Task CleanupAsync(CancellationToken cancellationToken = default)
        {
            _logger.LogInformation("开始执行数据字典缓存刷新任务，时间: {UtcNow}", DateTime.UtcNow);

            var stopwatch = Stopwatch.StartNew();

            // 创建组合的 CancellationToken：支持外部取消 + 内部超时（30分钟）
            using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
            cts.CancelAfter(TimeSpan.FromMinutes(30)); // 30分钟超时

            try
            {
                await _categoryItemsManagement.RefreshAllAsync(cts.Token);

                stopwatch.Stop();
                _logger.LogInformation(
                    "数据字典缓存刷新任务成功完成，耗时: {ElapsedMilliseconds}ms",
                    stopwatch.ElapsedMilliseconds);
            }
            catch (OperationCanceledException ex) when (cts.Token.IsCancellationRequested)
            {
                stopwatch.Stop();
                _logger.LogWarning(
                    ex,
                    "数据字典缓存刷新任务因超时或被取消而中止，已执行时间: {ElapsedMilliseconds}ms",
                    stopwatch.ElapsedMilliseconds);

                // 可选择是否 rethrow；若调度器需要感知取消，建议保留
                throw;
            }
            catch (Exception ex)
            {
                stopwatch.Stop();
                _logger.LogError(
                    ex,
                    "数据字典缓存刷新任务执行失败，耗时: {ElapsedMilliseconds}ms，错误: {ErrorMessage}",
                    stopwatch.ElapsedMilliseconds,
                    ex.Message);

                throw;
            }
        }
    }
}